package org.feuyeux.opentracing.lib;

import com.google.common.collect.ImmutableMap;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.log.Fields;
import io.opentracing.propagation.Format;
import io.opentracing.tag.Tags;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.util.Map;

public class HttpClient {
    private final Tracer tracer;
    private final OkHttpClient client;

    public HttpClient(Tracer tracer) {
        this.tracer = tracer;
        this.client = new OkHttpClient();
    }

    public String getHttp(int port, String path, Map<String, String> paramMap) {
        try {
            HttpUrl.Builder builder = new HttpUrl.Builder().scheme("http").host("localhost").port(port).addPathSegment(path);
            paramMap.entrySet().forEach(kv -> {
                builder.addQueryParameter(kv.getKey(), kv.getValue());
            });
            HttpUrl url = builder.build();
            Request.Builder requestBuilder = new Request.Builder().url(url);

            Span activeSpan = tracer.activeSpan();
            Tags.SPAN_KIND.set(activeSpan, Tags.SPAN_KIND_CLIENT);
            Tags.HTTP_METHOD.set(activeSpan, "GET");
            Tags.HTTP_URL.set(activeSpan, url.toString());
            tracer.inject(activeSpan.context(), Format.Builtin.HTTP_HEADERS, new RequestBuilderCarrier(requestBuilder));

            Request request = requestBuilder.build();
            Response response = client.newCall(request).execute();

            Tags.HTTP_STATUS.set(activeSpan, response.code());
            if (response.code() != 200) {
                throw new RuntimeException("Bad HTTP result: " + response);
            }
            return response.body().string();
        } catch (Exception e) {
            Tags.ERROR.set(tracer.activeSpan(), true);
            tracer.activeSpan().log(ImmutableMap.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, e));
            throw new RuntimeException(e);
        }
    }

}
